package org.csu.mypetstore.controller;

import com.github.pagehelper.PageInfo;
import org.csu.mypetstore.domain.*;
import org.csu.mypetstore.persistence.ProductMapper;
import org.csu.mypetstore.service.AccountService;
import org.csu.mypetstore.service.AdminService;
import org.csu.mypetstore.service.CatalogService;
import org.csu.mypetstore.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.util.List;

@Controller
@RequestMapping("/admin")
public class AdminController {

    @Autowired
    private AdminService adminService;
    @Autowired
    private CatalogService catalogService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private OrderService orderService;

    @GetMapping("/viewLogin")
    public String viewLogin() {
        return "admin/login";
    }

    @PostMapping("/login")
    public String login(Admin admin, Model model, HttpSession httpSession) throws NoSuchAlgorithmException {
        Admin loginAdmin = adminService.login(admin.getId(),admin.getPwd());
        if(loginAdmin == null) {
            model.addAttribute("msg", "Invalid id or password. Login failed.");
            return "admin/login";
        }
        else {
            httpSession.setAttribute("loginAdmin", loginAdmin);
            model.addAttribute("loginAdmin", loginAdmin);
            return "admin/adminmain";
        }
    }

    @GetMapping("/viewAdminMain")
    public String viewAdminMain(Model model, HttpSession httpSession) {
        Admin loginAdmin = (Admin)httpSession.getAttribute("loginAdmin");
        if(loginAdmin == null) {
            model.addAttribute("msg", "Please login first.");
            return "admin/login";
        }
        else {
            model.addAttribute("loginAdmin", loginAdmin);
            return "admin/adminmain";
        }
    }

    @GetMapping("/quit")
    public String Quit(HttpSession httpSession) {
        httpSession.setAttribute("loginAdmin", null);
        return "admin/login";
    }

    @GetMapping("/viewProducts")
    public String viewProducts(Model model, HttpSession httpSession, int pageNum) {
        Admin loginAdmin = (Admin)httpSession.getAttribute("loginAdmin");
        if(loginAdmin != null) {
            PageInfo<Product> productPageInfo = catalogService.getProductPage(pageNum,5);
            List<Product> productList = productPageInfo.getList();
            model.addAttribute("productPageInfo", productPageInfo);
            model.addAttribute("productList", productList);
            return "admin/catalog/products";
        }
        else {
            model.addAttribute("msg", "Please login first.");
            return "admin/login";
        }
    }

    @GetMapping("/viewItems")
    public String viewItems(String productId, Model model) {
        List<Item> itemList = catalogService.getItemListByProduct(productId);
        model.addAttribute("itemList", itemList);
        model.addAttribute("productId", productId);
        return "admin/catalog/items";
    }

    @GetMapping("/viewUsers")
    public String viewUsers(Model model, HttpSession httpSession) {
        Admin loginAdmin = (Admin)httpSession.getAttribute("loginAdmin");
        if(loginAdmin != null) {
            List<Account> userList = accountService.getAllAcount();
            model.addAttribute("userList", userList);
            return "admin/account/users";
        }
        else {
            model.addAttribute("msg", "Please login first.");
            return "admin/login";
        }
    }

    @GetMapping("/viewOrders")
    public String viewOrders(Model model, HttpSession session) {
        Admin loginAdmin = (Admin)session.getAttribute("loginAdmin");
        if(loginAdmin != null) {
            List<Order> orderList = orderService.getAllOrder();
            model.addAttribute("orderList", orderList);
            return "admin/order/orders";
        }
        else {
            model.addAttribute("msg", "Please login first.");
            return "admin/login";
        }
    }

    @GetMapping("/viewEditAccount")
    public String viewEditAccount(String username, Model model) {
        Account editAccount = accountService.getAccount(username);
        model.addAttribute("editAccount", editAccount);
        return "admin/account/edituser";
    }

    @PostMapping("/editAccount")
    public String editAccount(Account account, Model model) throws NoSuchAlgorithmException {
        accountService.updateAccount(account);
        Account editAccount = accountService.getAccount(account.getUsername());
        model.addAttribute("editAccount", editAccount);
        model.addAttribute("editMsg", "Save successfully!");
        return "admin/account/edituser";
    }

    @GetMapping("/removeUser")
    public String removeUser(String username, Model model) {
        Account removeAccount = accountService.getAccount(username);
        accountService.removeAccount(removeAccount);
        List<Account> userList = accountService.getAllAcount();
        model.addAttribute("userList", userList);
        model.addAttribute("removeUserMsg", "Remove successfully!");
        return "admin/account/users";
    }

    @GetMapping("/removeOrder")
    public String removeOrder(int orderId, Model model) {
        Order order = orderService.getOrder(orderId);
        orderService.removeOrder(order);
        List<Order> orderList = orderService.getAllOrder();
        model.addAttribute("orderList", orderList);
        model.addAttribute("changeMsg", "Delete successfully!");
        return "admin/order/orders";
    }

    @GetMapping("/removeProduct")
    public String removeProduct(String productId, Model model) {
        Product product = catalogService.getProduct(productId);
        catalogService.removeProduct(product);
        PageInfo<Product> productPageInfo = catalogService.getProductPage(1,5);
        List<Product> productList = productPageInfo.getList();
        model.addAttribute("productPageInfo", productPageInfo);
        model.addAttribute("productList", productList);
        model.addAttribute("changeMsg", "Delete successfully!");
        return "admin/catalog/products";
    }

    @GetMapping("/removeItem")
    public String removeItem(String itemId, Model model) {
        Item item = catalogService.getItem(itemId);
        catalogService.removeItem(item);
        List<Item> itemList = catalogService.getItemListByProduct(item.getProduct().getProductId());
        model.addAttribute("itemList", itemList);
        model.addAttribute("changeMsg", "Delete successfully!");
        return "admin/catalog/items";
    }

    @GetMapping("/dispatchStatus")
    public String dispatchStatus(int orderId, Model model) {
        Order order = orderService.getOrder(orderId);
        orderService.dispatchStatus(order);
        List<Order> orderList = orderService.getAllOrder();
        model.addAttribute("orderList", orderList);
        model.addAttribute("changeMsg", "Status change successfully!");
        return "admin/order/orders";
    }

    @GetMapping("/finishStatus")
    public String finishStatus(int orderId, Model model) {
        Order order = orderService.getOrder(orderId);
        orderService.finishStatus(order);
        List<Order> orderList = orderService.getAllOrder();
        model.addAttribute("orderList", orderList);
        model.addAttribute("changeMsg", "Status change successfully!");
        return "admin/order/orders";
    }

    @GetMapping("/changeItemStatus")
    public String changeItemStatus(String itemId, Model model) {
        Item item = catalogService.getItem(itemId);
        catalogService.changeItemStatus(item);
        List<Item> itemList = catalogService.getItemListByProduct(item.getProduct().getProductId());
        model.addAttribute("itemList", itemList);
        return "admin/catalog/items";
    }

    @GetMapping("/viewEditItem")
    public String viewEditItem(String itemId, Model model) {
        Item editItem = catalogService.getItem(itemId);
        model.addAttribute("editItem", editItem);
        return "admin/catalog/edititem";
    }

    @GetMapping("/viewAddItem")
    public String viewAddItem(String productId, Model model) {
        model.addAttribute("productId", productId);
        return "admin/catalog/additem";
    }

    @PostMapping("/editItem")
    public String editItem(Item item, Model model) {
        try {
            catalogService.UpdateItem(item);
            model.addAttribute("editMsg", "Save successfully!");
        } catch (Exception e) {
            model.addAttribute("failMsg", "ERROR! Please try again.");
        }
        Item editItem;
        if(item.getEditId() == null || item.getEditId().equals("")){
            editItem = catalogService.getItem(item.getItemId());
        }
        else {
            editItem = catalogService.getItem(item.getEditId());
        }
        model.addAttribute("editItem", editItem);
        return "admin/catalog/edititem";
    }

    @GetMapping("/viewEditOrder")
    public String viewEditOrder(int orderId, Model model) {
        Order editOrder = orderService.getOrder(orderId);
        List<LineItem> lineItems = editOrder.getLineItems();
        model.addAttribute("editOrder", editOrder);
        model.addAttribute("lineItems", lineItems);
        return "admin/order/editorder";
    }

    @PostMapping("/addItem")
    public String addItem(Item item, Model model) {
        try {
            catalogService.addItem(item);
            model.addAttribute("changeMsg", "Add successfully.");
            List<Item> itemList = catalogService.getItemListByProduct(item.getProductId());
            model.addAttribute("itemList", itemList);
            model.addAttribute("productId", item.getProductId());
            return "admin/catalog/items";
        } catch (Exception e) {
            model.addAttribute("productId", item.getProductId());
            model.addAttribute("failMsg", "ERROR! Please try again.");
            return "admin/catalog/additem";
        }
    }

    @PostMapping("/editOrder")
    public String editAccount(Order order, Model model) {
        orderService.updateOrder(order);
        Order editOrder = orderService.getOrder(order.getOrderId());
        List<LineItem> lineItems = editOrder.getLineItems();
        model.addAttribute("editOrder", editOrder);
        model.addAttribute("lineItems", lineItems);
        model.addAttribute("editMsg", "Save successfully!");
        return "admin/order/editorder";
    }

    @GetMapping("/viewEditProduct")
    public String viewUpload(String productId, Model model) {
        Product editProduct = catalogService.getProduct(productId);
        model.addAttribute("editProduct", editProduct);
        /*******************获取描述的文字部分*******************/
        String word = editProduct.getDescription();
        int index = word.lastIndexOf("<br/><br/>") + 10;
        word = word.substring(index);
        model.addAttribute("word", word);
        /***************************************************/
        return "admin/catalog/editproduct";
    }

    @PostMapping("/editProduct")
    public String editProduct(Product product,String word, Model model) {
        Product editProduct = catalogService.getProduct(product.getProductId());
        /*******************获取描述的图片部分*******************/
        String description = editProduct.getDescription();
        int index = description.lastIndexOf("<br/><br/>");
        String img = description.substring(0, index);
        product.setDescription(img+"<br/><br/>"+word);
        /***************************************************/
        try {
            catalogService.updateProduct(product);
            model.addAttribute("editMsg", "Save successfully!");
        } catch (Exception e) {
            model.addAttribute("failMsg", "ERROR! Please try again.");
        }
        if(product.getEditId() == null || product.getEditId().equals("")){
            editProduct = catalogService.getProduct(product.getProductId());
        }
        else {
            editProduct = catalogService.getProduct(product.getEditId());
        }
        model.addAttribute("editProduct", editProduct);
        /*******************获取描述的文字部分*******************/
        word = editProduct.getDescription();
        index = word.lastIndexOf("<br/><br/>") + 10;
        word = word.substring(index);
        model.addAttribute("word", word);
        /***************************************************/
        return "admin/catalog/editproduct";
    }

    @GetMapping("/viewEditImage")
    public String viewEditImage(String productId, Model model) {
        Product editProduct = catalogService.getProduct(productId);
        model.addAttribute("editProduct", editProduct);
        return "admin/catalog/editImage";
    }


    @PostMapping("/editImage")
    public String editImage(String productId, Model model, MultipartFile file)
            throws IllegalStateException, IOException{
        Product editProduct = catalogService.getProduct(productId);
        /*******************获取描述的文字部分*******************/
        String word = editProduct.getDescription();
        int index = word.lastIndexOf("<br/><br/>") + 10;
        word = word.substring(index);
        model.addAttribute("word", word);
        /***************************************************/
        /**********************上传图片**********************/
        File toFile = null;
        if (file.equals("") || file.getSize() <= 0 || file == null) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(file.getOriginalFilename());
            UploadUtil.inputStreamToFile(ins, toFile);
            ins.close();
        }
        String url = UploadUtil.uploadImg(toFile, UploadConstant.API_TYPE,UploadConstant.PRIVATE_STRORAGE,UploadConstant.TOKEN,UploadConstant.URL).getJSONObject("data").getJSONObject("url").getString("ali");
        editProduct.setDescription("<image src=\""+url+"\"><br/><br/>"+word);
        catalogService.updateProduct(editProduct);
        /***************************************************/
        PageInfo<Product> productPageInfo = catalogService.getProductPage(1,5);
        List<Product> productList = productPageInfo.getList();
        model.addAttribute("productPageInfo", productPageInfo);
        model.addAttribute("productList", productList);
        return "admin/catalog/products";
    }

    @GetMapping("/viewAddProduct")
    public String viewAddProduct() {
        return "admin/catalog/addproduct";
    }

    @PostMapping("/addProduct")
    public String addProduct(Product product, Model model, MultipartFile file, String word)
            throws IllegalStateException, IOException{
        /**********************上传图片**********************/
        File toFile = null;
        if (file.equals("") || file.getSize() <= 0 || file == null) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(file.getOriginalFilename());
            UploadUtil.inputStreamToFile(ins, toFile);
            ins.close();
        }
        String url = UploadUtil.uploadImg(toFile, UploadConstant.API_TYPE,UploadConstant.PRIVATE_STRORAGE,UploadConstant.TOKEN,UploadConstant.URL).getJSONObject("data").getJSONObject("url").getString("ali");
        product.setDescription("<image src=\""+url+"\"><br/><br/>"+word);
        /***************************************************/
        try {
            catalogService.addProduct(product);
            model.addAttribute("changeMsg", "Add successfully.");
            PageInfo<Product> productPageInfo = catalogService.getProductPage(1,5);
            List<Product> productList = productPageInfo.getList();
            model.addAttribute("productPageInfo", productPageInfo);
            model.addAttribute("productList", productList);
            return "admin/catalog/products";
        } catch (Exception e) {
            e.printStackTrace();
            model.addAttribute("failMsg", "ERROR! Please try again.");
            return "admin/catalog/addproduct";
        }
    }

    @PostMapping("/searchProduct")
    public String searchProductById(Model model, String idKey, String categoryKey) {
        List<Product> productList;
        if(categoryKey.equals("ALL")) {
            productList = catalogService.searchProductById(idKey);
        }
        else {
            productList = catalogService.searchProductByIdAndCategory(idKey, categoryKey);
        }
        model.addAttribute("productList", productList);
        return "admin/catalog/searchProducts";
    }

}
